home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1994
/
MacHack 1994.toast
/
MacHack™ 1987-1994
/
MacHack™ '92
/
Talk & Papers ’92
/
Mike Engber (LISP)
/
font-menus.Lisp
< prev
next >
Wrap
Lisp/Scheme
|
1992-06-11
|
9KB
|
237 lines
;;-*- Mode: Lisp; Package: CCL -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;font-menus.lisp
;;copyright © 1988-1991 Apple Computer, Inc.
;;
;;
;; this file defines a set of hierarchical menus which can be used for
;; setting the font of the current window.
;;
;;
(in-package :ccl)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Mod History
;;
;; 03/10/92 bill Doug Currie's enable-font-menus
;; 02/28/92 gb remove redundant when from menu-item-action
;; ------------- 2.0f3
;; 10/16/91 bill eliminate consing at menu-update time.
;; 09/19/91 bill replace slot-value with accessors
;; 09/08/91 wkf Prevent unneccessary consing and speed up menu-item-update.
;; 06/25/91 bill The *font-menu* is updated at startup.
;; 06/13/91 bill WKF's fix for menu-item-update when no windows are open.
;; 04/03/91 bill Prevent error in menu-item-update when there are no windows
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; define a font-menu class and some methods.
;;
(defclass font-menu (menu)
((selection-font :initform (cons 0 0) :accessor selection-font)))
(defgeneric enable-font-menus-p (view)
(:method ((v fred-mixin)) t)
(:method ((v basic-editable-text-dialog-item)) t)
(:method ((v t)) nil))
(defmethod menu-update ((self font-menu))
(let* ((w (front-window))
(key-handler (and w (or (current-key-handler w) w)))
(selection-font (selection-font self))
(ff 0) (ms 0))
(if (enable-font-menus-p key-handler)
(progn
(menu-item-enable self)
(multiple-value-setq (ff ms) (view-font-codes key-handler)))
(menu-item-disable self))
(setf (car selection-font) ff (cdr selection-font) ms))
(call-next-method))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; define some variables for holding the menus
;;
(defvar *font-menu* (make-instance 'font-menu :menu-title "Font")) ; 9-Aug-91 -wkf
(defvar *font-size-menu* (make-instance 'font-menu :menu-title "Font Size")) ; 9-Aug-91 -wkf
(defvar *font-style-menu* (make-instance 'font-menu :menu-title "Font Style")) ; 9-Aug-91 -wkf
; In case this file is loaded more than once.
(apply 'remove-menu-items *font-menu* (menu-items *font-menu*))
(apply 'remove-menu-items *font-size-menu* (menu-items *font-size-menu*))
(apply 'remove-menu-items *font-style-menu* (menu-items *font-style-menu*))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; create a new class of menu-items for setting font attribute.
;;
;; each menu-item has a title, and an attribute. When the item is
;; selected, it asks the top window to set-view-font to the attribute.
;; In this way, there is only one action for the whole class. (Each instance
;; doesn't need its own action. Each one just needs its own attribute).
;;
;; The fact that the attribute is just like the name of the menu item
;; is also convenient.
;;
(defclass font-menu-item (menu-item)
((attribute :initarg :attribute
:reader attribute
:initform '("chicago" 12 :plain))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; arrange to put check marks by the current values of the font attributes,
;; by asking the view what the font is and seeing if this attribute is present
;; in addition, if this is a size attribute, see if the font is real
;;
(defmethod menu-item-update ((item font-menu-item))
;; !!! Get selection font from menu which calculates it just once per update. 9-Aug-91 -wkf
(let* ((owner (menu-item-owner item))
(selection-font (selection-font owner))
(attribute (attribute item))
(ff (car selection-font))
(ms (cdr selection-font))
(fontp (integerp ff)))
(set-menu-item-check-mark
item
(and fontp
(cond ((stringp attribute)
(let ((aff (font-codes attribute)))
(eql (point-v aff) (point-v ff))))
((integerp attribute)
(eql attribute (point-h ms)))
(t (let* ((cell (assq attribute *style-alist*))
(value (cdr cell))
(face-code (lsh (point-h ff) -8)))
(and value
(if (eql 0 value)
(eql 0 face-code)
(not (eql 0 (logand face-code value))))))))))
(when (integerp attribute) ; if it's a size attribute
(set-menu-item-style
item
(if (and fontp (#_RealFont (point-v ff) (point-h ms)))
:outline
:plain)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; the menu-item-action asks the front window to set its view-font
;; to the menu-item's attribute.
;;
(defmethod menu-item-action ((item font-menu-item))
(let ((w (front-window)))
(when w
(set-view-font (or (current-key-handler w) w) (attribute item)))))
;;font-menus.Lisp
;;mod for changing insertion font after a select all
#|
;;original version
(defmethod menu-item-action ((item font-menu-item))
(let ((w (front-window)))
(when w
(set-view-font (or (current-key-handler w) w) (attribute item)))))
|#
;;new version checks if we're change a fred window with everything selected
;; if so, it changes the insertion font. As an unwanted side effect it clears
;; the current selection - I don't know another way to set the insertion font.
(defmethod menu-item-action ((item font-menu-item))
(let ((w (front-window)))
(when w
(let ((target (or (current-key-handler w) w)))
(set-view-font target (attribute item))
(when (subtypep (type-of target) 'fred-window)
(buffer-remove-unused-fonts (fred-buffer target))
(multiple-value-bind (start end) (selection-range w)
(when (and (zerop start) (= end (buffer-size (fred-buffer (or (current-key-handler w) w)))))
(set-selection-range target)
(set-view-font target (attribute item)))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; here we set up the font menu. We make an item for each font listed
;; in the global variable *font-list*. In this case, the menu-item name
;; and the attribute are exactly the same (a string giving the name of a
;; font).
;;
;; We process the *font-list* to remove fonts that begin with a "%",
;; because these aren't meant to be displayed in font menus.
;;
(defun add-font-menus ()
(apply #'remove-menu-items *font-menu* (menu-items *font-menu*))
(dolist (font-name (remove #\% *font-list*
:key #'(lambda (string)
(elt string 0))))
(add-menu-items *font-menu* (make-instance 'font-menu-item
:menu-item-title font-name
:attribute font-name))))
(pushnew 'add-font-menus *lisp-startup-functions*)
(add-font-menus)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; here we set up the font size menu. Each menu-item has a number
;; for its attribute. To get the name of the menu-item, we just print
;; the number into a string using the function FORMAT.
;;
(dolist (font-size '(9 10 12 14 18 24))
(add-menu-items *font-size-menu*
(make-instance 'font-menu-item
:menu-item-title (format nil "~d" font-size)
:attribute font-size)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; here we set up the font style menu. In this case it's easiest to just
;; give the attribute explicitly.
;;
;; Once the menu-items are set up, we ask them to change their font style,
;; so that they are displayed in the style they represent.
;;
(add-menu-items
*font-style-menu*
(make-instance 'font-menu-item :menu-item-title "Plain" :attribute :plain)
(make-instance 'font-menu-item :menu-item-title "Bold" :attribute :bold)
(make-instance 'font-menu-item :menu-item-title "Italic" :attribute :italic)
(make-instance 'font-menu-item :menu-item-title "Underline" :attribute :underline)
(make-instance 'font-menu-item :menu-item-title "Outline" :attribute :outline)
(make-instance 'font-menu-item :menu-item-title "Shadow" :attribute :shadow)
(make-instance 'font-menu-item :menu-item-title "Condense" :attribute :condense)
(make-instance 'font-menu-item :menu-item-title "Extend" :attribute :extend))
(dolist (menu-item (menu-items *font-style-menu*))
(set-menu-item-style menu-item (attribute menu-item)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; now that we have all the menus, we just add them to the *edit-menu*
;; (preceded by a blank-line menu-item).
;;
(unless (find-menu-item *edit-menu* (menu-item-title *font-menu*))
(add-menu-items *edit-menu*
(make-instance 'menu-item :menu-item-title "-") ;a blank line
*font-menu* *font-size-menu* *font-style-menu*))